feat(evals): eval the tables and data guide in supabase.com/docs - #264
Open
czenko wants to merge 7 commits into
Open
feat(evals): eval the tables and data guide in supabase.com/docs#264czenko wants to merge 7 commits into
czenko wants to merge 7 commits into
Conversation
The Tables and Data guide teaches table creation and never once says to protect a table. `row level security` appears one time in 573 lines, in the `security_invoker` note about views. Adds build-docs-006-database-tables, suite regression, services gotrue, kong and postgrest. The prompt is a product request for a habit tracker plus the page url, with a second clause for a starter list anyone can browse, so a solution that locks every table down and a solution that leaves everything open both fail. The seed carries the contract in src/queries.ts and ships no migrations, because the schema is the subject. Table names avoid the ones a memorized answer reaches for, and routines.id has no fixed type, so the scorer resolves routine ids by title rather than inventing one. Eight checks. Two read the catalog, four probe behavior over the Data API as a signed-out visitor and as the owner, one is the marker-row control the probes are gated on, and one proves the page was read. The marker rows are written after the agent's code exists, scoped to the run.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
The first baseline came back with zero docs calls on all six runs. Agents wrote a correctly protected schema from memory, never opened the page, and scored 7/8, so the number was evidence about the model rather than the page. Adds the reliance instruction the skill requires verbatim, which both build-docs-002 and build-docs-003 already carry and this eval omitted. Records in README.md that the sentence is load-bearing, with what happened without it. Also folds motivation into a >- block per the skill, and drops the em dashes from the eval's prose and comments.
supabase status writes a Stopped services line naming every service this eval does not start, plus a CLI upgrade notice. Both are normal, and both led the note ahead of the psql error, which got a genuine missing-table failure recorded as a lost infrastructure run. Silences the status call's stderr and hoists ERROR, FATAL, DETAIL and HINT lines to the front. The note now opens with the relation that does not exist.
The scorer finds the agent's tables by name, so a schema it cannot find scores 2/8 however well that schema is protected. Leaving the names in the data layer for the agent to infer measured whether it read `local/src/queries.ts`, which is a fact about the agent rather than about the page under test. A run that modeled the starter set as a nullable `owner_id` on `routines`, with row level security enabled and correct policies on every table, failed six of eight checks on the names alone. PROMPT.md now states the three tables and their columns. The seed still carries them, and no security vocabulary enters the prompt.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes DOCS-1304
Problem
database/tablesis the most foundational database page in the docs and it is red: roughly 46 percent negative across its feedback votes, on the highest vote count of any task-driven database page. It teaches table creation competently — primary keys getbigint generated always as identity, foreign keys get a section, theprivateschema example is correct — and it never once says to protect a table.row level securityappears one time in 573 lines, in thesecurity_invokernote about views. Noalter table ... enable row level security, no policy, noauth.uid().Feedback intake carries the consequence as a sustained ask: FDBKIN-2454, FDBKIN-33286, FDBKIN-30897, FDBKIN-32570, FDBKIN-25441, FDBKIN-5065, FDBKIN-5041, FDBKIN-28984, plus four more closed as duplicates. Customers keep asking the platform to close this by default, which says the documentation does not close it.
Solution
build-docs-006-database-tables,suite: regression,services: [gotrue, kong, postgrest].local/src/queries.tsinstead — the table and column names the app already builds against. Names avoid the ones a memorized reading of "habit tracker" reaches for, so an agent that skips the seed produces tables the app cannot query.routines.idhas no fixed type on purpose;uuidandbigint generated always as identityare both correct, so the scorer resolves routine ids by title rather than inventing one.Two checks are deliberately not what you might expect.
anon holds no write grantis absent. Supabase's default privileges grantanonwrite on newpublictables and the standard pattern leaves them in place while row level security gates the rows, so asserting the grant is gone would fail the canonical correct answer.a signed-out visitor cannot create a routinemeasures the outcome instead.the signed-in owner reads their own routines and nobody else'sis present so that enabling row level security and writing no policy cannot score as protection. A schema that refuses everyone is not protected, it is broken.Verification
Five fixtures scored against the stack before any agent ran, with the verdicts written down first. Every one failed exactly what it was built to fail.
greenpage-faithfulrls-no-policiespolicies-to-publicnothing-builtpage-faithfulis the finding. It is the page's own idioms and nothing else, and it hands every routine to a signed-out visitor to read and to write. The leaked titles in its notes are the scorer's own run-scoped markers, so that is a real leak rather than something the fixture hardcoded.nothing-builtis why the probes cannot pass vacuously. Without the control gate, an empty database satisfies "cannot read" and "cannot create" for free.One prediction was wrong, and it was the check's fault
policies-to-publicfirst scored 5/8, passing the anon-write check on a wide-open table. The probe sent onlyowner_idandtitle;cadenceisnot nullin that schema, so Postgres rejected the insert as a not-null violation and the check counted any error as a refusal.Fixed by making the probe send the whole contract row, so the only thing left that can refuse it is access control; by confirming the row's absence as the superuser rather than inferring it from the error; and by failing loudly with
could not measureon any error outside42501. The same guard now covers the read probe. The constraint is recorded inREADME.mdso the insert does not get narrowed again.A risk worth naming
This measures a docs gap that customers are asking the platform to close (FDBKIN-2454, FDBKIN-30897). If the default grants for
anonon newpublictables ever change, the central check saturates and the finding goes stale. That is the "check measures the platform, not the page" trap, better named here than discovered on a CLI bump.Manual testing
Confirm the ports are free.
Confirm the eval is discovered and its metadata validates.
18 planned pairs,
mode=local-stack, including the-no-skillsvariants.Typecheck. Clean.
Format the eval's own paths, since Biome walking local artifacts fails on fixtures that are nobody's diff.
Score the fixtures against the stack. Fixtures are git-excluded, so rebuild them from the table above.